package net.pws.common.persistence;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
 * 多页中的分页,封装了页面索引,页面数据,并提供了一些助手方法
 * <p>
 * 页面索引遵守Java的数组的习惯，从0开始.在展示的时候需要对页面索引进行处理
 */
public class ImmutablePage<T> implements Serializable, IPage<T> {
    
    public static final long serialVersionUID = 1L;
    
    /**
     * 默认的页面可装载的数据条目总和
     */
    public static final int DEFAULT_DATA_SIZE_IN_ONE_PAGE = 20;
    
    /**
     * 页面可装载的数据条目
     */
    protected int dataCountInOnePage = DEFAULT_DATA_SIZE_IN_ONE_PAGE;
    
    /**
     * 当前页面的索引
     */
    protected long currentPageNo;
    
    /**
     * 页面数据
     */
    protected List<T> data;
    
    /**
     * 所有的数据条目总数（所有的分页的数据累加）
     */
    protected long totalDataCount;
    
    /**
     * 
     */
    public ImmutablePage() {
        this(0, 0, DEFAULT_DATA_SIZE_IN_ONE_PAGE, Collections.EMPTY_LIST);
    }
    
    /**
     * @param currentPageNo
     *            当前页面的索引
     * @param totalCount
     *            所有的记录数
     * @param limitPerPage
     *            每页的记录数
     * @param data
     *            页面数据
     */
    public ImmutablePage(long currentPageNo, long totalCount, int limitPerPage, List<T> data) {
        if (0 > limitPerPage)
            throw new IllegalStateException("页面的数据大小不能为0！");
        this.currentPageNo = currentPageNo;
        this.totalDataCount = totalCount;
        this.dataCountInOnePage = limitPerPage;
        this.data = data;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getTotalDataCount()
     */
    public long getTotalDataCount() {
        return this.totalDataCount;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getTotalPageCount()
     */
    public long getTotalPageCount() {
        if (totalDataCount % dataCountInOnePage == 0)
            return totalDataCount / dataCountInOnePage;
        else
            return totalDataCount / dataCountInOnePage + 1;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getDataCountInOnePage()
     */
    public int getDataCountInOnePage() {
        return dataCountInOnePage;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getStartOfPage()
     */
    public int getStartOfPage() {
        return getStartOfPage((int)getCurrentPageNo(),getDataCountInOnePage());
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getData()
     */
    public List<T> getData() {
        return data;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#getCurrentPageNo()
     */
    public long getCurrentPageNo() {
        return currentPageNo;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#hasNextPage()
     */
    public boolean hasNextPage() {
        return this.getCurrentPageNo() < this.getTotalPageCount() - 1;
    }
    
    /* (non-Javadoc)
     * @see com.xlbs.common.persistence.IPage#hasPreviousPage()
     */
    public boolean hasPreviousPage() {
        return this.getCurrentPageNo() > 0;
    }
    
    /**
     * 获取页面的第一条数据在所有数据中的索引 默认每页可装载的数据最大为20，第5页的第一条数据在所有数据中的索引为100
     */
    public static int getStartOfPage(int pageNo) {
        return getStartOfPage(pageNo, DEFAULT_DATA_SIZE_IN_ONE_PAGE);
    }
    
    /**
     * 获取页面的第一条数据在所有数据中的索引 例如，每页可装载的数据最大数为30，第3页的第一条数据在所有数据中的索引为90
     */
    public static int getStartOfPage(int pageNo, int pageSize) {
        if (0 > pageNo)
            throw new IllegalArgumentException("页面索引不能小于0!");
        return pageNo * pageSize;
    }
     
}
